#! /bin/bash

cmd=$1
ip=$2
NICName=$3

function help() {
    cat <<-EOF
    Description:
        jm9200_openstack_x86 --- jm9200 OpenStack X86 config utils
        this installation script is only applicable to Ubuntu18.04-3 system. 

    Note:
        for all password: The all default value is "123". the passwords of all relevant services and components are set to 123.
        
    Usage:
        ./jm9200_openstack_x86 [options]

    options:
        -h      show this help
        -v      show virsion

    commands:
        createAllDB                         create all database and grant their privileges
        createKeystoneDB                    create keystone database and grant it privileges
        createGlanceDB                      create glance database and grant it privileges
        createPlaceme                       create placement database and grant it privileges
        createNovaDB                        create nova database and grant it privileges
        createNeutronDB                     create neutron database and grant it privileges

        removeAllDB                         remove all database
        removeKeystoneDB                    remove keystone database
        removeGlanceDB                      remove glance database
        removePlacementDB                   remove placement database
        removeNovaDB                        remove nova database
        removeNeutronDB                     remove neutron database

        updateSourceAndIPConfig -ip -NIC    update source

        openstackEnvironment                install all oepnstack package
        mysqlAndMemcachedConfig             config of mysql and memcached
        rabbitmqConfig                      config of rabbitmq
        keystoneConfig                      config of keystone
        glanceConfig                        config of glance
        placementConfig                     config of placement
        novaConfig                          config of nova
        neutronConfig                       config of neutron
        dashboardConfig                     config of dashboard 

        oneStepDeployment                   one step deployment of openstack

        restartAllService                   restart all service
        stopAllService                      stop all service
        enableAllService                    enable all service
        restartAfterReboot                  restart service after reboot
        clearLog                            clear all log of openstack service      
        changeNetwork -ip -NIC              change network environment
EOF
    exit 0
}

function version() {
    cat <<-EOF
	jm9200_openstack_x86 utils v1.0.0
EOF
    exit 0

}

function removeKeystoneDB() {
    mysql -u root -p123 <<EOF
    DROP DATABASE keystone;   
EOF
}

function removeGlanceDB() {
    mysql -u root -p123 <<EOF
    DROP DATABASE glance;   
EOF
}

function removePlacementDB() {
    mysql -u root -p123 <<EOF
    DROP DATABASE placement;
EOF
}

function removeNovaDB() {
    mysql -u root -p123 <<EOF
    DROP DATABASE nova_api;
    DROP DATABASE nova;
    DROP DATABASE nova_cell0;
EOF
}

function removeNeutronDB() {
    mysql -u root -p123 <<EOF
    DROP DATABASE neutron;
EOF
}

function removeAllDB() {
    removeKeystoneDB
    removeGlanceDB
    removePlacementDB
    removeNovaDB
    removeNeutronDB
}

function createKeystoneDB() {
    mysql -u root -p123 <<EOF
    CREATE DATABASE keystone;
    GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY '123';   
EOF
}

function createGlanceDB() {
    mysql -u root -p123 <<EOF
    CREATE DATABASE glance;
    GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%'  IDENTIFIED BY '123';
EOF
}

function createPlacementDB() {
    mysql -u root -p123 <<EOF
    CREATE DATABASE placement;
    GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%'  IDENTIFIED BY '123';
EOF
}

function createNovaDB() {
    mysql -u root -p123 <<EOF
    CREATE DATABASE nova_api;
    CREATE DATABASE nova;
    CREATE DATABASE nova_cell0;
    GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%'  IDENTIFIED BY '123';
EOF
}

function createNeutronDB() {
    mysql -u root -p123 <<EOF
    CREATE DATABASE neutron;
    GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%'  IDENTIFIED BY '123';
EOF
}

function createAllDB() {
    createKeystoneDB
    createGlanceDB
    createPlacementDB
    createNovaDB
    createNeutronDB
}

function updateSourceAndIPConfig() {
    /bin/cp -rf ./conf/sources.list /etc/apt/sources.list

    sudo sed -i 's/\(GRUB_CMDLINE_LINUX_DEFAULT=\).*/\1"quiet splash intel_iommu=on kvm.ignore_msrs=1 vfio-pci.ids=0731:9200"/' /etc/default/grub
    echo 'vfio-pci' >/etc/modules-load.d/vfio-pci.conf

    if [[ $ip != "" && $NICName != "" ]]; then
        sudo sed -i 's/\(bind-address = \).*/\1'$ip'/' ./conf/99-openstack.cnf
        sudo sed -i 's/\(-l \).*/\1'$ip'/' ./conf/memcached.conf
        sudo sed -i 's/\(my_ip = \).*/\1'$ip'/' ./conf/nova.conf
        sudo sed -i 's/\(local_ip = \).*/\1'$ip'/' ./conf/linuxbridge_agent.ini
        sudo sed -i 's/\(physical_interface_mappings = provider:\).*/\1'$NICName'/' ./conf/linuxbridge_agent.ini
        sudo sed -i '/controller/d' /etc/hosts
        sudo sed -i '/127.0.1.1/d' /etc/hosts
        sudo sed -i '$a'$ip'	controller' /etc/hosts
    else
        echo "please input correct host ip and NIC name"
    fi
    /bin/cp -rf ./conf/hostname /etc/

    sudo update-grub

    apt update

    apt -y upgrade

    sleep 1

    sudo apt-get -y install software-properties-common dirmngr apt-transport-https
    sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'
    sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el] https://mirrors.aliyun.com/mariadb/repo/10.3/ubuntu bionic main'

    add-apt-repository cloud-archive:train <<EOF

EOF

    sleep 1
    sudo apt -y install qemu-kvm libvirt-clients virtinst libvirt-daemon-system bridge-utils ovmf xtightvncviewer tightvncserver virt-manager

    apt update
    apt -y upgrade

    echo 'config success!'
}

function openstackEnvironment() {
    apt -y install python3-openstackclient

    sleep 1

    apt -y install mariadb-server python-pymysql

    sleep 1

    apt -y install memcached python3-memcache

    sleep 1

    apt -y install rabbitmq-server

    sleep 1

    apt -y install keystone

    sleep 1

    apt -y install glance

    sleep 1

    apt -y install placement-api

    sleep 1

    apt -y install nova-api nova-conductor nova-novncproxy nova-scheduler

    sleep 1

    apt -y install neutron-server neutron-plugin-ml2 neutron-linuxbridge-agent neutron-l3-agent neutron-dhcp-agent neutron-metadata-agent

    sleep 1

    apt -y install openstack-dashboard
}

function mysqlAndMemcachedConfig() {
    /bin/cp -rf ./conf/99-openstack.cnf /etc/mysql/mariadb.conf.d/99-openstack.cnf
    /bin/cp -rf ./conf/memcached.conf /etc/memcached.conf

    service mysql restart

    service memcached restart

    mysql_secure_installation <<EOF
    123
    n
    y
    n
    y
    y
EOF
}

function rabbitmqConfig() {
    rabbitmqctl add_user openstack 123
    rabbitmqctl set_permissions openstack ".*" ".*" ".*"
}

function keystoneConfig() {
    /bin/cp -rf ./conf/keystone.conf /etc/keystone/keystone.conf

    su -s /bin/sh -c "keystone-manage db_sync" keystone
    keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
    keystone-manage credential_setup --keystone-user keystone --keystone-group keystone
    keystone-manage bootstrap --bootstrap-password 123 --bootstrap-admin-url http://controller:5000/v3/ --bootstrap-internal-url http://controller:5000/v3/ --bootstrap-public-url http://controller:5000/v3/ --bootstrap-region-id RegionOne

    /bin/cp -rf ./conf/apache2.conf /etc/apache2/apache2.conf

    service apache2 restart

    . admin-openrc
    openstack project create --domain default --description "Service Project" service
    openstack project create --domain default --description "Demo Project" myproject
    openstack user create --domain default --password 123 myuser
    openstack role create myrole
    openstack role add --project myproject --user myuser myrole
}

function glanceConfig() {
    . admin-openrc
    openstack user create --domain default --password 123 glance
    openstack role add --project service --user glance admin
    openstack service create --name glance --description "OpenStack Image" image
    openstack endpoint create --region RegionOne image public http://controller:9292
    openstack endpoint create --region RegionOne image internal http://controller:9292
    openstack endpoint create --region RegionOne image admin http://controller:9292

    /bin/cp -rf ./conf/glance-api.conf /etc/glance/glance-api.conf

    su -s /bin/sh -c "glance-manage db_sync" glance
    service glance-api restart

    #glance image-create --name "uos" --file uos.iso --disk-format qcow2 --container-format bare --visibility public
}

function placementConfig() {
    . admin-openrc
    openstack user create --domain default --password 123 placement
    openstack role add --project service --user placement admin
    openstack service create --name placement --description "Placement API" placement
    openstack endpoint create --region RegionOne placement public http://controller:8778
    openstack endpoint create --region RegionOne placement internal http://controller:8778
    openstack endpoint create --region RegionOne placement admin http://controller:8778

    /bin/cp -rf ./conf/placement.conf /etc/placement/placement.conf

    su -s /bin/sh -c "placement-manage db sync" placement
    service apache2 restart
}

function novaConfig() {
    . admin-openrc
    openstack user create --domain default --password 123 nova
    openstack role add --project service --user nova admin
    openstack service create --name nova --description "OpenStack Compute" compute
    openstack endpoint create --region RegionOne compute public http://controller:8774/v2.1
    openstack endpoint create --region RegionOne compute internal http://controller:8774/v2.1
    openstack endpoint create --region RegionOne compute admin http://controller:8774/v2.1

    /bin/cp -rf ./conf/nova.conf /etc/nova/nova.conf

    su -s /bin/sh -c "nova-manage api_db sync" nova
    su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova
    su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova
    su -s /bin/sh -c "nova-manage db sync" nova
    su -s /bin/sh -c "nova-manage cell_v2 list_cells" nova

    systemctl restart nova-*

    sleep 1
    apt -y install nova-compute
    sleep 1

    openstack compute service list --service nova-compute

    service nova-compute restart

    sleep 8

    su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova
}

function neutronConfig() {
    . admin-openrc
    openstack user create --domain default --password 123 neutron
    openstack role add --project service --user neutron admin
    openstack service create --name neutron --description "OpenStack Networking" network
    openstack endpoint create --region RegionOne network public http://controller:9696
    openstack endpoint create --region RegionOne network internal http://controller:9696
    openstack endpoint create --region RegionOne network admin http://controller:9696

    /bin/cp -rf ./conf/neutron.conf /etc/neutron/neutron.conf
    /bin/cp -rf ./conf/ml2_conf.ini /etc/neutron/plugins/ml2/ml2_conf.ini
    /bin/cp -rf ./conf/linuxbridge_agent.ini /etc/neutron/plugins/ml2/linuxbridge_agent.ini
    /bin/cp -rf ./conf/l3_agent.ini /etc/neutron/l3_agent.ini
    /bin/cp -rf ./conf/dhcp_agent.ini /etc/neutron/dhcp_agent.ini
    /bin/cp -rf ./conf/metadata_agent.ini /etc/neutron/metadata_agent.ini
    /bin/cp -rf ./conf/radvd.conf /etc/radvd.conf

    ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini
    su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf   --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron

    systemctl restart radvd
    service nova-api restart

    modprobe br_netfilter
    systemctl restart nova-compute

    systemctl restart neutron-*
}

function dashboardConfig() {
    /bin/cp -rf ./conf/local_settings.py /etc/openstack-dashboard/local_settings.py
    /bin/cp -rf ./conf/openstack-dashboard.conf /etc/apache2/conf-available/openstack-dashboard.conf

    systemctl restart apache2.service
}

function restartAllService() {
    systemctl restart mysql
    systemctl restart memcached.service
    systemctl restart rabbitmq-server.service
    systemctl restart apache2.service
    systemctl restart glance-api
    systemctl restart nova-*
    systemctl restart libvirtd
    systemctl restart neutron-*

    echo " "
}

function stopAllService() {
    systemctl stop mysql
    systemctl stop memcached.service
    systemctl stop rabbitmq-server.service
    systemctl stop apache2.service
    systemctl stop glance-api
    systemctl stop nova-*
    systemctl stop libvirtd
    systemctl stop neutron-*

    echo " "
}

function enableAllService() {
    systemctl enable mysql
    systemctl enable memcached.service
    systemctl enable rabbitmq-server.service
    systemctl enable apache2.service
    systemctl enable glance-api
    systemctl enable nova-*
    systemctl enable libvirtd
    systemctl enable neutron-*
}

function restartAfterReboot() {
    systemctl restart rabbitmq-server.service
    systemctl restart memcached.service
    #systemctl restart neutron-*

    echo " "
}

function oneStepDeployment() {
    openstackEnvironment
    mysqlAndMemcachedConfig

    createAllDB
    rabbitmqConfig
    keystoneConfig
    glanceConfig
    placementConfig
    novaConfig
    neutronConfig
    dashboardConfig
}

function clearLog() {
    rm /var/log/nova/*
    rm /var/log/neutron/*
    rm /var/log/apache2/*
    rm /var/log/keystone/*
    rm /var/log/placement/*
    rm /var/log/glance/*
}

function changeNetwork() {
    if [[ $ip != "" && $NICName != "" ]]; then
        sudo sed -i 's/\(bind-address = \).*/\1'$ip'/' /etc/mysql/mariadb.conf.d/99-openstack.cnf
        sudo sed -i 's/\(-l \).*/\1'$ip'/' /etc/memcached.conf
        sudo sed -i 's/\(my_ip = \).*/\1'$ip'/' /etc/nova/nova.conf
        sudo sed -i 's/\(local_ip = \).*/\1'$ip'/' /etc/neutron/plugins/ml2/linuxbridge_agent.ini
        sudo sed -i 's/\(physical_interface_mappings = provider:\).*/\1'$NICName'/' /etc/neutron/plugins/ml2/linuxbridge_agent.ini
        sudo sed -i '/controller/d' /etc/hosts
        sudo sed -i '$a'$ip'	controller' /etc/hosts
    else
        echo "please input correct host ip and NIC name"
    fi

    systemctl restart networking network-manager
}

# function openstackVMConfig() {
#     folder="/var/lib/nova/instances"
#     for file in ${folder}/*; do
#         if [[ -f ${file}"/disk" && ! -f ${file}"/mark" ]]
#         then
#             sudo touch ${file}"/mark"
#             sudo mv ${file}"/disk" ${file}"/disk.temp"
#             sudo mv ${file}"/disk.eph0" ${file}"/disk"
#             sudo mv ${file}"/disk.temp" ${file}"/disk.eph0"
#         fi
#     done
# }

case $cmd in
-h | --help)
    help
    ;;
-v | --version)
    version
    ;;
createAllDB)
    createAllDB
    ;;
createKeystoneDB)
    createKeystoneDB
    ;;
createGlanceDB)
    createGlanceDB
    ;;
createPlacementDB)
    createPlacementDB
    ;;
createNovaDB)
    createNovaDB
    ;;
createNeutronDB)
    createNeutronDB
    ;;
removeAllDB)
    removeAllDB
    ;;
removeKeystoneDB)
    removeKeystoneDB
    ;;
removeGlanceDB)
    removeGlanceDB
    ;;
removePlacementDB)
    removePlacementDB
    ;;
removeNovaDB)
    removeNovaDB
    ;;
removeNeutronDB)
    removeNeutronDB
    ;;
updateSourceAndIPConfig)
    updateSourceAndIPConfig
    ;;
openstackEnvironment)
    openstackEnvironment
    ;;
mysqlAndMemcachedConfig)
    mysqlAndMemcachedConfig
    ;;
rabbitmqConfig)
    rabbitmqConfig
    ;;
keystoneConfig)
    keystoneConfig
    ;;
glanceConfig)
    glanceConfig
    ;;
placementConfig)
    placementConfig
    ;;
novaConfig)
    novaConfig
    ;;
neutronConfig)
    neutronConfig
    ;;
dashboardConfig)
    dashboardConfig
    ;;
restartAfterReboot)
    restartAfterReboot
    ;;
restartAllService)
    restartAllService
    ;;
stopAllService)
    stopAllService
    ;;
enableAllService)
    enableAllService
    ;;
oneStepDeployment)
    oneStepDeployment
    ;;
clearLog)
    clearLog
    ;;
changeNetwork)
    changeNetwork
    ;;
# openstackVMConfig)
#     openstackVMConfig
#     ;;
*)
    echo "error command $cmd"
    ;;
esac
